package gbench.sandbox.plot;

import org.junit.jupiter.api.Test;

import gbench.common.fs.FileSystem;
import gbench.common.matlib.MatlibCanvas;
import gbench.common.matlib.MatlibCanvas.NVec;
import gbench.common.matlib.matrix.Complex;
import gbench.common.matlib.matrix.ComplexMatrix;

import static gbench.common.matlib.MatlibCanvas.NVec.nveclc;
import static gbench.common.matlib.MatlibCanvas.PatternCase.*;
import static gbench.common.matlib.MatlibCanvas.println;
import static gbench.common.matlib.img.ImageOps.img2rgbinfo;
import static gbench.common.matlib.img.ImageOps.rgbinfo2xyrgbS;
import static gbench.common.matlib.matrix.Complex.*;
import static gbench.common.tree.LittleTree.timeit;
import static java.lang.Math.PI;
import static java.lang.Thread.sleep;

public class JunitFourier {

    @Test
    public void foo() throws InterruptedException {
        final var file = "C:/Users/Administrator/Pictures/pics/lena.jpg";
        final var rgbinfo = img2rgbinfo(FileSystem.path(file, this.getClass())); // 背景图纹
        final var width = rgbinfo.i4("width");
        final var height = rgbinfo.i4("height");
        final var size = 1000;
        final var matlib = new MatlibCanvas(size);
        final var w = 2 * PI / width;
        final var Fj = ComplexMatrix.of(width, height, (j, k) -> C2(w * j * k).exp()); // 傅里叶变换
        //final var Fj_ = ComplexMatrix.of(width, height, (j, k) -> C2(-w * j * k).exp());// 逆向傅里叶变换
        // 因为遍历rgbs的时候结果是(x:行索引,y：列索引,t：数据值)的原组结果。而绘图坐标的x是水平索引的所以数组的第一索引为宽度
        final var rgbs = new Complex[width][height]; // 颜色矩阵，
        rgbinfo2xyrgbS(rgbinfo, NVec::new).forEach(e -> {
            final var k = e.i4(0); // 水平坐标
            final var j = e.i4(1); // 垂直坐标
            final var r = C1(e.i4(2)); // 红色分量
            final var g = C1(e.i4(3)); // 绿色分量
            //final var b = C1(e.i4(4)); // 蓝色分量
            rgbs[k][height-j-1] = C(r.real(),g.real());
        });// 像素点

        matlib.plot(width, height, sess -> timeit(() -> {
                final var cmx = ComplexMatrix.build(rgbs);
                final var fj = Fj.mmult(cmx.transpose());
                timeit(()->{
                    fj.dataStream(p -> p.flattenS(nullcase(0d)
                            .typeof(Complex.class,Complex::mode)
                            .typeof(Number.class,Number::doubleValue)).collect(nveclc()
                    ).resize(5, 0)).forEach(sess::drawPoint);
                });
                println("shape", cmx.shape());
            }));
        sleep(50000);
    }
}
